<template>
<!-- 
  - @name echarts图表通用组件
  - @version 2021-09-23 20:49:59 星期四
  -->
    <div class="echart" ref="echart" style="height: 100%"></div>
</template>
<script>
/**
 * Props:
 *    echartsOption: echarts组件配置
 *    axisLayer： 当xy轴的文字太多导致显示不全，超出n个字符显示省略号（通过父组件设置）,鼠标滑过显示全
 *
 * Emit:
 *    on-click: 点击事件，返回点前点击的对象
 *    on-get-index: 点击事件，返回点击对象的索引
 *
 */

import * as echarts from "echarts";
export default {
    name: "EchartsCommon",
    props: {
        // echarts图表配置
        echartsOption: {
            type: Object,
            default: () => ({}),
        },
        // 鼠标滑过xy轴显示弹层配置，默认x轴
        axisLayer: {
            type: String,
            default: 'xAxis'
        }
    },
    data: () => {
        return {
            // echarts实例
            echarts: null
        }
    },

    mounted() {
        // 首次加载
        this.$nextTick(() => {
            this.echartsInit();
        });

        // 拖拽窗口
        window.addEventListener("resize", this.resizeEcharts);
    },
    destroyed () {
        // 销毁拖拽事件
        window.removeEventListener('resize', this.resizeEcharts)
    },
    methods: {
        /**
         * @name echarts初始化
         * @version 2021-04-10 11:33:32 星期六
         */
        echartsInit() {
            this.echarts = echarts.init(this.$refs.echart);
            this.echarts.clear();
            this.setOption();

            // 普通形式点击，返回当前点击对象
            this.echarts.off("click");
            setTimeout(() => {
                this.echarts.on("click", (e) => {
                    this.$emit("on-click", e);
                });
            }, 100)


            // 有些图形特殊，通过getZr()方法点击背景计算出点击的索引
            this.echarts.getZr().on("click", (params) => {
                const pointInPixel = [params.offsetX, params.offsetY];
                if (this.echarts.containPixel("grid", pointInPixel)) {
                    const pointInGrid = Math.abs(
                        this.echarts.convertFromPixel("grid", pointInPixel)[0]
                    );
                    //抛出当前的index下标
                    this.$emit("on-get-index", pointInGrid);
                } else {
                    //   console.log("点击的是背景...");
                }
            });


           /**
            * x或者轴文字可能太多导致重叠，这里实现超过n位显示省略号（n在axisLabel中通过formatter截取），鼠标滑过出现弹层展示全，
            * 需要在echarts配置中的xAxis设置triggerEvent: true,否则不能触发鼠标mouseover事件
            * 
           */
            this.echarts.on( 'mouseover', ( params ) => {
                const { componentType, value, event } = params;
                if ( componentType !== this.axisLayer ) return
                const overLayerDom = document.createElement('div');
                const { clientX, clientY } = event.event;
                overLayerDom.style.left = `${clientX}px`;
                overLayerDom.style.top = `${clientY}px`
                overLayerDom.innerText = value
                document.body.appendChild(overLayerDom);
                overLayerDom.classList.add('echarts-over-layer');
            })

            this.echarts.on( 'mouseout', ( params ) => {
                if ( params.componentType !== this.axisLayer ) return
                const overLayerDom = document.getElementsByClassName('echarts-over-layer')[0]
                // 防止抖动，dom可能为undefined，这里判断dom是否存在
                if ( overLayerDom ) {
                    overLayerDom.classList.remove('echarts-over-layer');
                }
            })
        },
        /**
         * @name echarts加载配置项
         * @version 2021-04-10 11:32:33 星期六
         */
        setOption() {
            this.echarts.setOption(this.echartsOption);
        },

        /**
        * @name 拖拽浏览器窗口，重置ecahrts
        * @version 2021-09-15 09:15:25 星期三
        */
        resizeEcharts () {
            if (this.echarts) {
                this.echarts.resize();
            }
        }
    },
    watch: {
        /**
         * @name 配置更新，重新设置
         * @description 防止动态更新配置
         * @version 2021-04-12 09:46:27 星期一
         */
        echartsOption: {
            handler() {
                if (this.echarts) {
                    this.setOption();
                }
            },
            deep: true,
        },
    },
};
</script>
<style>
.echarts-over-layer {
    position: absolute;
    color: #fff;
    background-color: rgba(0,0,0,.3);
    padding: 10px;
    border-radius: 5px;
    font-size: 12px;
}
</style>
